package org.erp.product.router;

import lombok.extern.log4j.Log4j2;
import org.erp.common.enums.DeviceInventoryEvent;
import org.erp.product.domain.dto.CallbackDto;
import org.erp.product.infrastructure.annotation.DeviceEvent;
import org.erp.product.infrastructure.exception.ProductException;
import org.erp.product.strategy.impl.DeviceEventHandler;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

@Log4j2
@Component
public class DeviceEventRouter {

    private final Map<DeviceInventoryEvent, Method> methodMap = new HashMap<>();
    private final Object handlerBean;

    public DeviceEventRouter(DeviceEventHandler handler) {
        this.handlerBean = handler;

        for (Method method : handler.getClass().getMethods()) {
            DeviceEvent annotation = method.getAnnotation(DeviceEvent.class);
            if (annotation != null) {
                methodMap.put(annotation.value(), method);
            }
        }
    }

    public void dispatch(CallbackDto callbackDto) {
        log.info("回调参数为: 目标事件为-> {},批次标识为-> {},回调成功库存信息为-> {},操作人信息为-> {},{},接驳人信息为-> {},{}"
                , callbackDto.getTargetEvent()
                , callbackDto.getBatchId()
                , callbackDto.getConnectLogAddDtoList().stream()
                        .map(String::valueOf).collect(Collectors.joining(","))
                , callbackDto.getOperationId(), callbackDto.getOperationName()
                , callbackDto.getTransferId(), callbackDto.getTransferName());
        Method method = methodMap.get(callbackDto.getTargetEvent());
        if (method == null) {
            throw new ProductException("不支持的事件类型：" + callbackDto.getTargetEvent());
        }

        try {
            method.invoke(handlerBean, callbackDto);
        } catch (Exception e) {
            throw new ProductException("事件处理失败：" + e.getCause().getMessage());
        }
    }
}
